package com.aruba.circleprogressbar;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

public class CircleProgressBar extends View {
    private int backgroundColor;
    private int progressColor;
    private int progressWidth;
    private int radius_px;
    private int textSize;
    private int textColor;
    private int progress;
    private int maxProgress;

    private Paint bgPaint = new Paint();
    private Paint pgPaint = new Paint();
    private Paint textPaint = new Paint();

    public CircleProgressBar(Context context) {
        this(context, null);
    }

    public CircleProgressBar(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CircleProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        if (attrs == null) return;
        TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.CircleProgressBar);
        backgroundColor = typedArray.getColor(R.styleable.CircleProgressBar_backgroundColor, Color.BLACK);
        progressColor = typedArray.getColor(R.styleable.CircleProgressBar_progressColor, Color.WHITE);
        progressWidth = typedArray.getDimensionPixelSize(R.styleable.CircleProgressBar_progressWidth, 10);
        radius_px = typedArray.getDimensionPixelSize(R.styleable.CircleProgressBar_radius, 100);
        textSize = typedArray.getDimensionPixelSize(R.styleable.CircleProgressBar_android_textSize, dpToPx(getContext(), 16));
        textColor = typedArray.getColor(R.styleable.CircleProgressBar_android_textColor, Color.BLACK);
        maxProgress = typedArray.getInt(R.styleable.CircleProgressBar_maxProgress, 100);
    }

    private void init() {
        setRadius_px(radius_px);

        bgPaint.setAntiAlias(true);
        bgPaint.setColor(backgroundColor);
        bgPaint.setStrokeWidth(progressWidth);
        bgPaint.setStyle(Paint.Style.STROKE);

        pgPaint.setAntiAlias(true);
        pgPaint.setColor(progressColor);
        pgPaint.setStrokeWidth(progressWidth);
        pgPaint.setStyle(Paint.Style.STROKE);
        pgPaint.setStrokeCap(Paint.Cap.ROUND);

        textPaint.setAntiAlias(true);
        textPaint.setColor(textColor);
        textPaint.setTextSize(textSize);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        init();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        drawBgProgress(canvas);
        drawProgress(canvas);
        drawText(canvas);
    }

    private void drawBgProgress(Canvas canvas) {
        canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, radius_px, bgPaint);
    }

    private void drawProgress(Canvas canvas) {
        float left, top, right, bottom;
        int centerX = getMeasuredWidth() / 2;
        int centerY = getMeasuredHeight() / 2;
        left = centerX - radius_px;
        top = centerY - radius_px;
        right = centerX + radius_px;
        bottom = centerY + radius_px;
        RectF rectF = new RectF(left, top, right, bottom);
        canvas.drawArc(rectF, 0, 360f * progress / maxProgress, false, pgPaint);
    }

    private void drawText(Canvas canvas) {
        Paint.FontMetrics m = new Paint.FontMetrics();
        textPaint.getFontMetrics(m);
        int baseLine = (int) (getMeasuredHeight() / 2 - (m.top + m.bottom) / 2);

        String text = (int) ((float) progress / maxProgress * 100) + "%";
        canvas.drawText(text, getMeasuredWidth() / 2 - textPaint.measureText(text) / 2, baseLine, textPaint);
    }

    public int dpToPx(Context context, int size) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (size * scale + 0.5f);
    }

    public int getBackgroundColor() {
        return backgroundColor;
    }

    @Override
    public void setBackgroundColor(int backgroundColor) {
        this.backgroundColor = backgroundColor;
    }

    public int getProgressColor() {
        return progressColor;
    }

    public void setProgressColor(int progressColor) {
        this.progressColor = progressColor;
    }

    public int getProgressWidth() {
        return progressWidth;
    }

    public void setProgressWidth(int progressWidth) {
        this.progressWidth = progressWidth;
    }

    public int getRadius_px() {
        return radius_px;
    }

    public void setRadius_px(int radius_px) {
        int manRadius = getMeasuredHeight() > getMeasuredWidth() ? getMeasuredWidth() : getMeasuredHeight();
        radius_px = radius_px > manRadius ? manRadius : radius_px;
        this.radius_px = radius_px;
    }

    public int getTextSize() {
        return textSize;
    }

    public void setTextSize(int textSize) {
        this.textSize = textSize;
    }

    public int getTextColor() {
        return textColor;
    }

    public void setTextColor(int textColor) {
        this.textColor = textColor;
    }

    public int getProgress() {
        return progress;
    }

    public void setProgress(int progress) {
        progress = progress > maxProgress ? maxProgress : progress;
        this.progress = progress;
        postInvalidate();
    }

    public int getMaxProgress() {
        return maxProgress;
    }

    public void setMaxProgress(int maxProgress) {
        this.maxProgress = maxProgress;
    }
}
